﻿#pragma once
#include <functional>


namespace Ysz
{
	template<class T>
	class shared_ptr
	{

	public:
		explicit shared_ptr(T* ptr )//不允许隐式类型转换
			:_ptr(ptr)
			,_count(new int(1))
		{
		
		}
		template<class D>//定制删除器
		shared_ptr(T* ptr , D del)
			:_ptr(ptr)
			, _count(new int(1))
			, _del(del)
		{

		}


		shared_ptr(const shared_ptr<T>& sptr)
		{
			_ptr = sptr._ptr;
			_count = sptr._count;
			_del = sptr._del;
			(*_count)++; 
			
		}

		shared_ptr<T>& operator= (const shared_ptr<T>& sptr)
		{
			if (_ptr != sptr._ptr)
			{
				release();
				_ptr = sptr._ptr;
				_count = sptr._count;
				_del = sptr._del;
				(*_count)++;
			}
			return *this;
		}


		~shared_ptr()
		{
			release();
		}



		T& operator*()
		{
			return *_ptr;
		}


		T* operator->()
		{
			return _ptr;
		}


		void release()
		{
			if(--(*_count) == 0)
			{
				//delete _ptr;
				_del(_ptr);
				delete _count;
			}
		}

	private:
		T* _ptr;
		int* _count;
		std::function<void(T*)> _del = [](T* ptr) {delete ptr; };

	};

}